#include "Vector.h"
#include <cmath>

Vector3::Vector3(float x, float y, float z): x(x), y(y), z(z) { }

Vector3 Vector3::operator+(const Vector3 & other) const {
  return Vector3(x + other.x, y + other.y, z + other.z);
}

Vector3 Vector3::operator-(const Vector3 & other) const {
  return Vector3(x - other.x, y - other.y, z - other.z);
}

Vector3 Vector3::normalize() const {
  float l = length();
  if(fabs(l) < 0.0001) return Vector3();
  else return (*this)/l;
}

float Vector3::length() const {
  return sqrt(squaredLength());
}

float Vector3::squaredLength() const {
  return dotProduct(*this, *this);
}

Point3::Point3(float x, float y, float z): x(x), y(y), z(z) { }

Point3::Point3(const Vector3 & vector) {
  x = vector.x;
  y = vector.y;
  z = vector.z;
}

Point3 Point3::operator+(const Vector3 & vector) const {
  return Point3(x + vector.x, y + vector.y, z + vector.z);
}

Vector3 Point3::operator-(const Point3 & other) const {
  return Vector3(x - other.x, y - other.y, z - other.z);
}

Vector3 Point3::toVector3() const {
  return Vector3(x, y, z);
}

float dotProduct(const Vector3 & v1, const Vector3 & v2) {
  return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}

Vector3 crossProduct(const Vector3 & v1, const Vector3 & v2) {
  float x = v1.y * v2.z - v1.z * v2.y;
  float y = v1.z * v2.x - v1.x * v2.z;
  float z = v1.x * v2.y - v1.y * v2.x;

  return Vector3(x, y, z);
}

Vector3 operator*(float value, const Vector3 & vector) {
  return Vector3(vector.x * value, vector.y * value, vector.z * value);
}

Vector3 operator*(const Vector3 & vector, float value) {
  return Vector3(vector.x * value, vector.y * value, vector.z * value);
}

Vector3 operator/(const Vector3 & vector, float value) {
  return Vector3(vector.x / value, vector.y / value, vector.z / value);
}
